<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/12/5
 * Time: 18:12
 */

namespace wechatpay;


class WxH5
{
    protected $config;
    protected $appid;
    protected $mch_id;
    protected $notify_url;
    protected $key;
    protected $ip;
    protected $trade_type;
    public function __construct()
    {
        $this->config=Config::config();
        $this->appid=$this->config['appid'];
        $this->mch_id=$this->config['mch_id'];;
        $this->notify_url=$this->config['notify_url'];
        $this->key=$this->config['key'];
//        $this->ip=$this->get_client_ip();//115.60.61.92 swoole_get_local_ip
//        $this->ip=$this->request()->getHeaders()['real-ip']??'获取失败';//115.60.61.92 swoole_get_local_ip
        $this->ip='115.60.61.92';//
        $this->trade_type='MWEB';
    }
    public function sign($ip,$nonce_str,$out_trade_no,$scene_info,$total_fee,$body=''){
        $signA ="appid=$this->appid&body=$body&mch_id=$this->mch_id&nonce_str=$nonce_str&notify_url=$this->notify_url&out_trade_no=$out_trade_no&scene_info=$scene_info&spbill_create_ip=$ip&total_fee=$total_fee&trade_type=$this->trade_type";
        $strSignTmp = $signA."&key=$this->key"; //拼接字符串  注意顺序微信有个测试网址 顺序按照他的来 直接点下面的校正测试 包括下面XML  是否正确
        $sign = strtoupper(MD5($strSignTmp)); // MD5 后转换成大写
        return $sign;
    }
    public function post_data($ip,$body,$nonce_str,$out_trade_no,$scene_info,$total_fee,$sign){
        $post_data="<xml>
                    <appid>$this->appid</appid>
                    <body>$body</body>
                    <mch_id>$this->mch_id</mch_id>
                    <nonce_str>$nonce_str</nonce_str>
                    <notify_url>$this->notify_url</notify_url>
                    <out_trade_no>$out_trade_no</out_trade_no>
                    <scene_info>$scene_info</scene_info>
                    <spbill_create_ip>$ip</spbill_create_ip>
                    <total_fee>$total_fee</total_fee>
                    <trade_type>$this->trade_type</trade_type>
                    <sign>$sign</sign>
                    </xml>";//拼接成XML 格式
        return $post_data;
    }
//    /**
//     * 订单查询
//     *
//     */
//    public function orderQuery( $out_trade_no = '' )
//    {
//        $config = [
//            'out_trade_no' => $out_trade_no,
//            'appid' => $this->appid,
//            'mch_id' => $this->mch_id,
//            'nonce_str' => self::getNonceStr()
//        ];
//        $this->values = $config;
//        $sign = $this->sign();      //生成sign签名
//        $this->values['sign'] = $sign;
//        $xmlstr = $this->ToXml();   //生成微信请求xml数据格式
//        $url = "https://api.mch.weixin.qq.com/pay/orderquery";  //查询订单url
//        $dataxml = self::postXmlCurl( $xmlstr, $url, false );//传参调用curl请求
//        $objectxml = $this->xmlToArray( $dataxml );
//        if ( $objectxml['return_code'] == 'SUCCESS' && $objectxml['result_code'] == 'SUCCESS' && $objectxml['trade_state'] == 'SUCCESS' ) {
//            return true;
//        } else {
//            return false;
//        }
//    }
    public function headers(){
        $headers = array();
        $headers[] = 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8';
        $headers[] = 'Connection: Keep-Alive';
        $headers[] = 'Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3';
        $headers[] = 'Accept-Encoding: gzip, deflate';
        $headers[] = 'User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:22.0) Gecko/20100101 Firefox/22.0';
        return $headers;
    }
    /**
     * 获取客户端ip
     * @return string
     */
    public function get_client_ip() {
        if(getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
            $ip = getenv('HTTP_CLIENT_IP');
        } elseif(getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {
            $ip = getenv('HTTP_X_FORWARDED_FOR');
        } elseif(getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {
            $ip = getenv('REMOTE_ADDR');
        } elseif(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
            $ip = $_SERVER['REMOTE_ADDR'];
        }
        return preg_match ( '/[\d\.]{7,15}/', $ip, $matches ) ? $matches [0] : '';
    }
    /**
     * 发送请求
     * @param $url
     */
    public function http_post($url='',$post_data=array(),$header=array(),$timeout=30) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 跳过证书检查
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);  // 从证书中检查SSL加密算法是否存在
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
        $response = curl_exec($ch);
        curl_close($ch);
        return $response;
    }

    public function postXmlCurl( $url,  $xml,$useCert = false, $second = 30 )
    {
        $ch = curl_init();
        //设置超时
        curl_setopt( $ch, CURLOPT_TIMEOUT, $second );

        curl_setopt( $ch, CURLOPT_URL, $url );
        curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, TRUE );
        curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, 2 );//严格校验
        //设置header
        curl_setopt( $ch, CURLOPT_HEADER, FALSE );
        //要求结果为字符串且输出到屏幕上
        curl_setopt( $ch, CURLOPT_RETURNTRANSFER, TRUE );

//        if ( $useCert == true ) {
//            //设置证书
//            //使用证书：cert 与 key 分别属于两个.pem文件
//            curl_setopt( $ch, CURLOPT_SSLCERTTYPE, 'PEM' );
//            curl_setopt( $ch, CURLOPT_SSLCERT, self::SSLCERT_PATH );
//            curl_setopt( $ch, CURLOPT_SSLKEYTYPE, 'PEM' );
//            curl_setopt( $ch, CURLOPT_SSLKEY, self::SSLKEY_PATH );
//        }
        //post提交方式
        curl_setopt( $ch, CURLOPT_POST, TRUE );
        curl_setopt( $ch, CURLOPT_POSTFIELDS, $xml );
        //运行curl
        $data = curl_exec( $ch );
        //返回结果
        if ( $data ) {
            curl_close( $ch );
            return $data;
        } else {
            $error = curl_errno( $ch );
            curl_close( $ch );
            throw new \Exception( "curl出错，错误码:$error" );
        }
    }
}